package com.huiquan.body.service;

import com.huiquan.body.dao.BodyOrganDao;
import com.huiquan.body.dao.BodyOrganSymptomDao;
import com.huiquan.body.domain.BodyOrgan;
import com.huiquan.body.domain.BodyOrganSymptom;
import com.huiquan.body.domain.BodyOrganSymptomVO;
import com.huiquan.foundation.util.BusinessUtil;
import com.huiquan.framework.base.BaseService;
import com.huiquan.framework.base.ReturnCode;
import com.huiquan.framework.base.ReturnData;
import com.huiquan.framework.utils.GetListUtil;
import com.huiquan.framework.utils.ReturnUtil;
import com.huiquan.management.constant.MigrateCode;
import com.huiquan.management.service.MigrateService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import java.io.File;
import java.io.IOException;
import java.util.*;

/**
 * @author lichao email:lichao@witspring.com
 * @Description:
 * @Date 2018/2/24 15:10
 * @since Ver V
 */
@Service
public class BodyService extends BaseService {

    @Autowired
    private BodyOrganDao bodyOrganDao;

    @Autowired
    private BodyOrganSymptomDao bodyOrganSymptomDao;

    @Autowired
    private MigrateService migrateService;

    public ModelAndView organList(String startStr) {
        int start = startStr == null ? 1 : Integer.parseInt(startStr);
        // 初始化过滤的条件
        Map<String, Object> param = new HashMap<>();

        // 获取数据总量
        int totalSize = bodyOrganDao.selectOrganCount(param);

        // 获取翻页相关
        Map<String, Integer> pageNo = GetListUtil.getPageNoMap(totalSize, start);
        int startIndex = pageNo.get("startIndex");

        // 获取列表
        List<BodyOrgan> list = new ArrayList<>();
        if (startIndex < totalSize) {
            param.put("startIndex", startIndex);
            list = bodyOrganDao.selectOrganList(param);
        }

        Map<String, Object> map = GetListUtil.getReturnMap2(totalSize, pageNo.get("start"), startIndex,
                pageNo.get("endPage"), list, null);
        return new ModelAndView("body/index", map);
    }

    /**
     * 编辑一个器官
     *
     * @param image
     * @param organ
     * @return
     */
    public ReturnData editOrgan(MultipartFile image, BodyOrgan organ, String id) {
        if (image != null && !image.isEmpty()) {
            // 上传文件
            try {
                uploadImage(image, organ.getPicture());
            } catch (IOException e) {
                ReturnCode rc = ReturnCode.DYNAMIC_DESC_EXCEPTION;
                rc.setDesc("文件上传失败");
                return ReturnUtil.fail(rc);
            }
        }
        if (StringUtils.isNotEmpty(id)) {
            // 更新到mysql
            organ.setId(Long.parseLong(id));
            bodyOrganDao.update(organ);
        } else {
            // 插入到mysql
            bodyOrganDao.insert(organ);
        }
        return ReturnUtil.success();
    }


    /**
     * 删除一个器官
     *
     * @param id
     * @return
     */
    public ReturnData deleteOrgan(Long id) {
        try {
            bodyOrganDao.deleteById(id);
        } catch (Exception e) {
            ReturnCode rc = ReturnCode.DYNAMIC_DESC_EXCEPTION;
            rc.setDesc("器官删除失败");
            return ReturnUtil.fail(rc);
        }
        return ReturnUtil.success();
    }

    /**
     * 上传图片保存路径
     */
    @Value("${body.image.path}")
    private String uploadImagePath;

    /**
     * 人体图图片映射的虚拟路径
     */
    private static final String BODY_IMAGE_PATH = "/body/";

    /**
     * 上传图片到服务器
     *
     * @param image     图片文件流
     * @param imageName 图片名
     * @return
     * @throws IOException
     * @throws IllegalStateException
     */
    private String uploadImage(MultipartFile image, String imageName) throws IllegalStateException, IOException {
        String path = uploadImagePath + imageName;
        File file = new File(path);
        image.transferTo(file);
        return BODY_IMAGE_PATH + imageName;
    }

    /**
     * 上传图片保存路径
     */
    @Value("${body.image.export.script}")
    private String exportImageScript;

    /**
     * 导出人体图器官
     *
     * @throws Exception
     */
    public void generateBodyOrgan() throws Exception {
        // 从mysql取数据
        Map<String, Object> params = new HashMap<>();
        List<BodyOrgan> list = bodyOrganDao.selectOrganList(params);
        Map<Long, BodyOrgan> organMap = new HashMap<>();
        Set<Long> parentIdSet = new HashSet<>();
        for (BodyOrgan organ : list) {
            organMap.put(organ.getId(), organ);
            parentIdSet.add(organ.getParentId());
        }
        // 生成数据字符串
        StringBuilder builder = new StringBuilder();
        for (BodyOrgan organ : list) {
            // 如果该器官是某个器官的父器官则不导出为一行数据
            if (parentIdSet.contains(organ.getId())) {
                continue;
            }
            Long parentId = organ.getParentId();
            String name = organ.getName();
            while (parentId != 0) {
                name = organMap.get(parentId).getName().concat(";").concat(name);
                parentId = organMap.get(parentId).getParentId();
            }
            builder.append(name).append("\t").append(organ.getSex()).append("\t").append(organ.getRank()).append("\t").append(organ.getPicture()).append("\n");
        }
        // 导出到181
        migrateService.migrateFileByCodeAndString(MigrateCode.BODY_ORGAN, builder.toString());
        // 导出到hive
        migrateService.migrateHiveByCodeAndString(MigrateCode.BODY_ORGAN_HIVE, builder.toString());
        // 导出图片
        LOGGER.info("开始导出图片到181");
        BusinessUtil.excuteShell(new String[]{exportImageScript});
        LOGGER.info("导出图片完毕");
    }

    public ModelAndView symptomList(String startStr) {
        int start = startStr == null ? 1 : Integer.parseInt(startStr);
        // 初始化过滤的条件
        Map<String, Object> param = new HashMap<>();

        // 获取数据总量
        int totalSize = bodyOrganSymptomDao.selectSymptomVOCount(param);

        // 获取翻页相关
        Map<String, Integer> pageNo = GetListUtil.getPageNoMap(totalSize, start);
        int startIndex = pageNo.get("startIndex");

        // 获取列表
        List<BodyOrganSymptomVO> list = new ArrayList<>();
        if (startIndex < totalSize) {
            param.put("startIndex", startIndex);
            list = bodyOrganSymptomDao.selectSymptomVOList(param);
        }
        Map<String, Object> map = GetListUtil.getReturnMap2(totalSize, pageNo.get("start"), startIndex,
                pageNo.get("endPage"), list, null);
        List<BodyOrgan> organList = bodyOrganDao.selectOrganList(new HashMap<String, Object>());
        map.put("organList", organList);
        return new ModelAndView("body/index", map);
    }

    /**
     * 编辑一个器官
     *
     * @param bodyOrganSymptom
     * @param id
     * @return
     */
    public ReturnData editOrganSymptom(BodyOrganSymptom bodyOrganSymptom, String id) {
        if (StringUtils.isNotEmpty(id)) {
            // 更新到mysql
            bodyOrganSymptom.setId(Long.parseLong(id));
            bodyOrganSymptomDao.update(bodyOrganSymptom);
        } else {
            // 插入到mysql
            bodyOrganSymptomDao.insert(bodyOrganSymptom);
        }
        return ReturnUtil.success();
    }

    /**
     * 删除一个器官症状
     *
     * @param id
     * @return
     */
    public ReturnData deleteOrganSymptom(Long id) {
        try {
            bodyOrganSymptomDao.deleteById(id);
        } catch (Exception e) {
            ReturnCode rc = ReturnCode.DYNAMIC_DESC_EXCEPTION;
            rc.setDesc("器官症状删除失败");
            return ReturnUtil.fail(rc);
        }
        return ReturnUtil.success();
    }

    /**
     * 导出人体图器官
     *
     * @throws Exception
     */
    public void generateBodyOrganSymptom() throws Exception {
        // 从mysql取数据
        Map<String, Object> params = new HashMap<>();
        List<BodyOrganSymptomVO> list = bodyOrganSymptomDao.selectSymptomVOList(params);
        // 生成数据字符串
        StringBuilder builder = new StringBuilder();
        for (BodyOrganSymptomVO vo : list) {
            builder.append(vo.getOrganName()).append("\t").append(vo.getSex()).append("\t").append(vo.getSymptom()).append("\t").append(vo.getRank()).append("\n");
        }
        // 导出到181
        migrateService.migrateFileByCodeAndString(MigrateCode.BODY_ORGAN_SYMPTOM, builder.toString());
    }
}
